package crp.core.shared.expression;

import com.google.common.collect.Maps;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.qwlabs.cdi.DispatchInstance;

import javax.enterprise.context.ApplicationScoped;
import javax.enterprise.inject.Instance;
import javax.inject.Inject;
import java.util.Map;

@ApplicationScoped
public class ExpressionService {
    private final Map<String, AviatorEvaluatorInstance> expressionInstances = Maps.newConcurrentMap();
    private final DispatchInstance<String, ExpressionInstanceInitializer> dispatcher;

    @Inject
    public ExpressionService(Instance<ExpressionInstanceInitializer> instance) {
        this.dispatcher = DispatchInstance.of(instance);
    }

    public AviatorEvaluatorInstance getInstance(String topic) {
        return expressionInstances.computeIfAbsent(topic, this::initialize);
    }

    private AviatorEvaluatorInstance initialize(String topic) {
        AviatorEvaluatorInstance instance = AviatorEvaluator.newInstance();
        instance.setCachedExpressionByDefault(true);
        dispatcher.stream(topic)
                .forEach(initializer -> initializer.initialize(instance));
        return instance;
    }

}
